CS 116: Introduction to Computer Science 2

CS 116 Tutorial 3 (Solutions): Strings, Input/Output

Reminders:

  • Assignment 03 is due on Wed, Feb 5th at 10 AM

  1. Write a function closest_integer that has no arguments, but instead reads in a floating point number from console input with a prompt "What's the number?", and returns the closest integer to that number. This function rounds ties up, so that:

    closest_integer()
    What's the number?: 0.5
    will return 1,

    while both of these (below)

    closest_integer()closest_integer()
    What's the number?: -0.5What's the number?: 0.3

    will return 0.

    DO NOT use round in your solution.

    Solution:

    import check
    
    
    def closest_integer():
        '''
        returns the integer closest to the value entered by the user, always 
        round 0.5 up to the next largest integer.
        Effects: Reads in a float from console input
        
        closest_integer: None -> Int
        
        Examples:
        if the user types in 0, closest_integer returns 0
        if the user types in 0.3, closest_integer returns 0
        if the user types in -1.5, closest_integer returns -1
        if the user types in -1.8, closest_integer returns -2
        if the user types in 1.8, closest_integer returns 2
        '''
        n = float(input ("What's the number?"))
        base_number = int(n)
        after_decimal = n - int(n)
        if after_decimal < -0.5:
            return base_number-1
        elif after_decimal >= 0.5:
            return base_number+1
        return base_number
    
    # additional tests:
    check.set_input('-1.3')
    check.expect('-1.3', closest_integer(), -1)
    check.set_input('0.5')
    check.expect('0.5', closest_integer(), 1)
    check.set_input('0')
    check.expect('0', closest_integer(), 0)
    check.set_input('0.3')
    check.expect('0.3', closest_integer(), 0)
    check.set_input('-1.5')
    check.expect('-1.5', closest_integer(), -1)
    check.set_input('-1.8')
    check.expect('-1.8', closest_integer(), -2)
    check.set_input('1.8')
    check.expect('1.8', closest_integer(), 2)
  2. Write a function create_date that consumes nothing, but takes keyboard input. The program has three prompts: "Enter the year: ", "Enter the month: " and "Enter the day: ". The function then returns a date in the form "dd/mm/yyyy", where dd is a 2 digit number (between 01 and 31, depending on the month), mm is a 2 digit number (between 01 and 12) and yyyy is a 4 digit number.

    For example,
    create_date()
    Enter the year: 1996
    Enter the month: 06
    Enter the day: 17
    => "17/06/1996"

    Use string methods and string formatting (using {}) to complete the question

    Solution:

    import check
    
    
    def create_date():
        '''
        prompts the user for three strings, reads in the year, the month 
        and the day respectively for each string, and returns the date in 
        the form "dd/mm/yyy".
        Effects: Prints three prompts to the user, reads in a year, a month and a day.
    
        create_date: None -> Str
    
        Examples:
        if the user enters "1996", "06", "17" when create_date() is called, 
        "17/06/1996" is returned
        if the user enters "2016", "05", "25" when create_date() is called, 
        "25/05/2016" is returned
        '''
        year = input("Enter the year: ")
        month = input("Enter the month: ")
        day = input("Enter the day: ")
        new_format = "{0}/{1}/{2}".format(day, month, year)
        return new_format
    
    # Tests
    check.set_input("1996", "06", "17")
    check.expect("17/06/1996", create_date(), "17/06/1996")
    check.set_input("2016", "05", "25")
    check.expect("25/05/2016", create_date(), "25/05/2016")
    check.set_input("2000", "01", "01")
    check.expect("01/01/2000", create_date(), "01/01/2000")
  3. Write a function fill_the_string that consumes a non-empty string s and a positive integer n, and returns an n-letter string that consists of copies of s, where the last one is perhaps a partial copy.

    For example,
    fill_the_string("love", 12) => "lovelovelove"
    fill_the_string("truth", 12) => "truthtruthtr"

    Solution:

    import check
    
    
    def fill_the_string(s, n):
        '''
        returns an n-letter string made up of copies of s; the final copy might 
        not be a complete copy.
        
        fill_the_string: Str Nat -> Str
        requires: s is non-empty, n > 0
    
        Examples:
        fill_the_string("n", 0) => ""
        fill_the_string("love", 12) => "lovelovelove"
        fill_the_string("truth", 12) => "truthtruthtr"
        '''
        num_full_copies = n // len(s)
        leftover_bits = n % len(s)
        return s * num_full_copies + s[:leftover_bits]
    
    # Tests:
    check.expect("n is 1", fill_the_string("n", 1), "n")
    check.expect("One full copy", fill_the_string("love", 4), "love")
    check.expect("Three full copies", fill_the_string("love", 12), "lovelovelove")
    check.expect("Partial copy", fill_the_string("love", 2), "lo")
    check.expect("Full copies+partial copy", fill_the_string("truth", 12), 
                 "truthtruthtr")
    check.expect("Long full copies+partial copy", fill_the_string("love", 22), 
                 "lovelovelovelovelovelo")
    A few comments:
    1) There are much longer ways to write this function, which are certainly fine.
    2) Notice: It's not okay to name the function fill-the-string. Scheme is unusual in allowing the - character in the name of a function or variable. Python doesn't allow it. The underscore character is okay.
    3) We used integer division here when we divided n by len(s). That gave us the right number of complete copies of s we needed.
    4) If we'd had s * n // len (s), it wouldn't have worked. We would have first computed s * n (the string with n copies of s), and then been supposed to use // to divide this by len(s). But this gives this error:
    TypeError: unsupported operand type(s) for //: 'str' and 'int'
    5) You might have had the idea of using floating point multiplication, and tried to multiply s by a float. But that doesn't work, either:
    >> "love" * 3.5
    TypeError: can't multiply sequence by non-int of type 'float'

  4. Write a recursive function sum_up that has no parameters but takes input from the keyboard. This function prompts the user with "Enter the amount of numbers to sum: ", followed by "Enter an integer: " which will read input the amount of times as the number entered before. The function then prints a message "The sum is n", where n is the sum of all the integers that were entered.

    For example,
    Enter the amount of numbers to sum: 4
    Enter an integer: 3
    Enter an integer: 56
    Enter an integer: 7
    Enter an integer: 8
    The sum is 74

    Solution:

    import check
    
    
    def read_and_sum(total,current_amount_read,total_amount_to_read):
        '''
        returns the sum of input numbers by prompting messages and reads
          in a series of integers
        Effects: Prints prompts to the user and reads in a series of integers
        read_and_sum: Nat Nat Nat -> Nat
        '''
        if current_amount_read == total_amount_to_read:
            return total
        else:
            read_in = input("Enter an integer: ")
            total = total + int(read_in)
            current_amount_read = current_amount_read + 1
            return read_and_sum(total,current_amount_read,total_amount_to_read)
    
    def sum_up():
        '''
        prints out a message with the sum of all input integers by prompting
          messages and reads in a series of integers, with the initial integer
          corresponding to the amount of integers to be summed
        Effects: Prints prompts to the user and reads in a series of integers,
          prints out a message with the sum of all input integers
        sum_up: None -> None
        Examples:
          If the user input is ["1', "1"], sum_up() prints "The sum is 1"
          If the user input is ["4", "3", "56", "7", "8"],
            sum_up() prints "The sum is 74"
        '''
        amount_to_read = int(input("Enter the amount of numbers to sum: "))
        total_sum = read_and_sum(0,0,amount_to_read)
        print("The sum is {0}".format(total_sum))
        return                   ## optional
    
    # Tests
    check.set_input("1","1")
    check.set_screen("The sum is 1")
    check.expect("sum is 1", sum_up(), None)
    
    check.set_input("4", "3", "56", "7", "8")
    check.set_screen("The sum is 74")
    check.expect("sum is 74", sum_up(), None)
    
    check.set_input("5", "1", "2", "3", "4", "5")
    check.set_screen("The sum is 15")
    check.expect("sum is 15", sum_up(), None)
    
    
  5. We've seen the function str.count() in lectures. Using recursion, implement a version of the function, called my_string_count(s, c) where s is any string, and c is a string of length one. my_string_count(s, c) will return the number of times that the character c appears in the string s.

    For example,
    my_string_count("hello world", "l") => 3
    my_string_count("abracadabra", "e") => 0
    my_string_count("", "e") => 0

    Solution:

    import check
    
    def my_string_count(s, c):
        '''
        returns the number of times that the single character c appears in s
        
        my_string_count: Str Str -> Nat
        requires: len(c) == 1
        
        Examples: 
        my_string_count("", "a") => 0
        my_string_count("Hello World", "l") => 3
        my_string_count("The tragedy of Darth Plagueis the Wise", "t") => 3
        '''
        if s == "":
            return 0
        elif s[0] == c:
            return 1 + my_string_count(s[1:], c)
        else:
            return my_string_count(s[1:], c)
        
    check.expect("empty s", my_string_count("", "s"), 0)
    check.expect("single instance", my_string_count("super", "s"), 1)
    check.expect("repeated instance", my_string_count("systematic", "s"), 2)
    check.expect("no instance", my_string_count("long time, no see", "c"), 0)
    check.expect("special characters (!)", my_string_count("Wow!", "!"), 1)
    check.expect("numeral string", my_string_count("1729", "2"), 1)
    check.expect("large repetition", my_string_count("abcd"*30, "b"), 30)
    check.expect("capitals", my_string_count("AaaAaksAaa", "A"), 3)
    
    

Valid XHTML 1.0 Strict

Last modified on Sunday, 02 February 2020, at 08:54.